The personal computer has evolved from a luxury that was mainly utilized for word processing to a common household item that is utilized to manage finances, control lighting, security and entertainment systems, pay bills, store recipes, search for information, purchase/sell goods, participate in gaming, complete school assignments, etc. The evolution has been facilitated by developments and/or advancements in electrical/electronics related technologies (e.g., chip manufacturing, bus topologies, transmission medium, etc.) and software related technologies (e.g., operating systems, programming languages, networks, etc.). Such developments and/or enhancements have reduced component size, manufacturing, labor and business (MLB) expenses, and power consumption, for example, and have rendered high-performance/low cost user-friendly computing machines. Similarly, various technological developments and/or advances have transformed mainframes and workstations from basic data processing machines employed by businesses to efficient computing machines that automate control of entire plants, facilitate creating and sharing documentation, and connect employees/companies that reside in different locations around the world.
A typical computing machine is provided with software (e.g., an Operating Systems (OS) that provides a framework to execute and/or build applications, view data, control apparatuses, etc. Traditional OSs were developed under a single thread approach, wherein individual processes (e.g., tasks) are handled one at a time. For instance, if five processes were ready for execution, the CPU processes only one of the processes at any given time while the remaining processes are queued for subsequent processing. Such systems commonly employed one or more mechanisms to interrupt processing and transparently re-use resources, for example, to handle higher priority processes.
Advances in the arts lead to the introduction of a multithreaded-multitasking environment, which set forth a notion of concurrent execution of multiple processes or subprocesses. However, with multithreaded-multitasking systems concurrent execution is constrained by the number of processors a particular computing machine employs, wherein the number of processes that can be concurrently processed is proportional to the number of processors. Thus, a single CPU multitasking system, in reality, does not process tasks concurrently. Rather, a hybrid approach is utilized that can appear to concurrently execute processes. For example, in many systems, CPU cycles are shared across multiple processes, but only one process can consume the CPU at a time and respective processes are provided with the CPU for a limited time.
Many conventional single CPU multitasking (multithreaded) systems utilize a time-slice technique to simulate concurrent process execution and preserve responsiveness of any one task to the user or external computing nodes, including devices. For example, the CPU can be utilized to execute at least a portion of one process for one or more clock cycles (a time slice) while processes awaiting the CPU can be stored in a run queue or transition to a “sleep” or “wait” state. Upon lapse of the time slice, access to the CPU can be halted regardless of whether processing is completed; in many systems, the time slice is associated with a grace period to provide for smooth termination of processing resources after a time slice expires. The CPU can then be provided to another process for a time slice. This cycle can continue and eventually a second, third, fourth, etc. time slice is provided in order to complete execution of a process.
In many instances, sharing a system's CPU is transparent to a user and appears to provide “true” concurrent processing; although, as noted above, concurrent processing does not occur in a single CPU system. This scenario typically occurs when a few simple processes are executing. However, when CPU/memory hungry applications are executing, competition for limited processing resources and time slice-based processing (serial processing) can be readily apparent to a user. For example, a common phenomenon experienced when running several applications (e.g., word processing, spreadsheet, database, computation, etc.) is increased delay between the time a user issues an event (e.g., a mouse click) and completion of an associated task. Examples of this phenomenon include increased time to save a document or render characters on a display after pressing a key on a keyboard. In some instances, the demand for processing resources can result in a momentary system “hang” and/or a premature termination (e.g., re-boot) without invocation or instruction by the user.
The time-sharing model is a good implementation technique for abstracting true concurrency in a system and allowing a developer to program targeting the desired concurrency of their program, independent of the target. However, it requires heavy weight scheduling mechanisms and, in many cases, processor support so the thread transition is seamless and correct (not observable). Additionally, it fails to guarantee responsiveness under all circumstances since it does not require upfront reservation of resources (e.g., CPU, memory, peripheral bandwidth, etc.). Furthermore, the treatment of resources is not uniform; CPU cycles are managed transparently or with adhoc hints from the user. Memory resources and device bandwidth are managed in yet another way. In addition, the hardware system is required to have a “heartbeat” or clock tick so it can periodically check all threads/processes to determine whether they are ready for execution or if the time slice has expired. This is computationally expensive and the periodic timer consumes power cycles. The time-sharing, multi-tasking/threading model also requires a complex programming model, commonly referred to as a threading model, which is often misused and difficult to get right.